﻿namespace ThreeByte.ActiveDeck.Dashboard
{
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    using ActiveDeck.Dashboard.LoginUI;
    using System;
    using System.ServiceModel.DomainServices.Client.ApplicationServices;

    /// <summary>
    /// <see cref="UserControl"/> class providing the main UI for the application.
    /// </summary>
    public partial class MainPage : UserControl
    {

        private readonly AuthenticationService _authService = WebContext.Current.Authentication;

        /// <summary>
        /// Creates a new <see cref="MainPage"/> instance.
        /// </summary>
        public MainPage() {
            InitializeComponent();

            this._authService.LoggedIn += new EventHandler<AuthenticationEventArgs>(_authService_LoggedIn);
            this._authService.LoggedOut += new EventHandler<AuthenticationEventArgs>(_authService_LoggedOut);
            this.UpdateLoginState();
        }

        void _authService_LoggedOut(object sender, AuthenticationEventArgs e) {
            this.UpdateLoginState();
            ContentFrame.Navigate(new Uri("/Login", UriKind.Relative));
        }

        void _authService_LoggedIn(object sender, AuthenticationEventArgs e) {
            this.UpdateLoginState();
            if(RedirectUri != null) {
                ContentFrame.Navigate(RedirectUri);
            } else {
                ContentFrame.Navigate(new Uri("/Home", UriKind.Relative));
            }
            RedirectUri = null;
        }

        /// <summary>
        /// After the Frame navigates, ensure the <see cref="HyperlinkButton"/> representing the current page is selected
        /// </summary>
        private void ContentFrame_Navigated(object sender, NavigationEventArgs e) {
            foreach(UIElement child in LinksStackPanel.Children) {
                HyperlinkButton hb = child as HyperlinkButton;
                if(hb != null && hb.NavigateUri != null) {
                    if(hb.NavigateUri.ToString().Equals(e.Uri.ToString())) {
                        VisualStateManager.GoToState(hb, "ActiveLink", true);
                    } else {
                        VisualStateManager.GoToState(hb, "InactiveLink", true);
                    }
                }
            }
        }

        private Uri RedirectUri;

        /// <summary>
        /// If an error occurs during navigation, show an error window
        /// </summary>
        private void ContentFrame_NavigationFailed(object sender, NavigationFailedEventArgs e) {
            e.Handled = true;
            ErrorWindow.CreateNew(e.Exception);
        }

        private void ContentFrame_Navigating(object sender, NavigatingCancelEventArgs e) {
            if(IsLoginUri(e.Uri)) {
                //Allow user to continue
                return;
            } 
            if(!WebContext.Current.User.IsAuthenticated) {
                RedirectUri = e.Uri;
                e.Cancel = true;
                this.UpdateLoginState();
                ContentFrame.Navigate(new Uri("/Login", UriKind.Relative));
                return;
            }
            if(!(UserHasPermission(e.Uri))){
                e.Cancel = true;
                ContentFrame.Navigate(new Uri("/Home", UriKind.Relative));
            }
        }

        public void PromptLogin() {
            ContentFrame.Navigate(new Uri("/Redirect", UriKind.Relative));
        }
        
        //TODO: There has to be a better way to implement permissioned access
        private bool UserHasPermission(Uri uri) {
            if(uri.OriginalString.Contains("Developer")) {
                if(WebContext.Current.User.IsInRole("Developer")) {
                    return true;
                }
            } else if(uri.OriginalString.Contains("Inspect")) {
                if(WebContext.Current.User.IsInRole("Developer")) {
                    return true;
                }
            } else if(uri.OriginalString.Contains("Error")) {
                if(WebContext.Current.User.IsInRole("Developer")) {
                    return true;
                }
            } else if(uri.OriginalString.Contains("Participants")) {
                if(WebContext.Current.User.IsInRole("Presenter")) {
                    return true;
                }
            } else {
                return true;
            }

            return false;
        }

        private bool IsLoginUri(Uri uri) {
            return (uri.OriginalString.EndsWith("/Login")
                    || uri.OriginalString.EndsWith("/Redirect"));
        }

        private void UpdateLoginState() {
            if(WebContext.Current.User.IsAuthenticated) {
                LinksBorder.Visibility = Visibility.Visible;
                if(WebContext.Current.User.IsInRole("Developer")) {
                    //Show the developer tab
                    DeveloperLink.Visibility = Visibility.Visible;
                } else {
                    //Don't
                    DeveloperLink.Visibility = Visibility.Collapsed;
                }
                if(WebContext.Current.User.IsInRole("Presenter")) {
                    //Show the Participants tab
                    ParticipantsLink.Visibility = Visibility.Visible;
                } else {
                    //Don't
                    ParticipantsLink.Visibility = Visibility.Collapsed;
                }

            } else {
                LinksBorder.Visibility = Visibility.Collapsed;
            }
        }

       
    }
}